﻿CREATE PROCEDURE [dbo].[Text_BookTree_Check]
	@bookId UNIQUEIDENTIFIER
AS
BEGIN
	RETURN 0

	-- Левый ключ ВСЕГДА меньше правого
	IF EXISTS(SELECT * FROM [dbo].[text_BookTree] WHERE [BookId] = @bookId AND [LeftKey] >= [RightKey])
	BEGIN
		RAISERROR ('Левый ключ ВСЕГДА меньше правого', 16, 1)
		RETURN 1
	END

	DECLARE @count INT, @minKey BIGINT, @maxKey BIGINT
	SELECT @count = COUNT([BookTreeId]), @minKey = MIN([LeftKey]), @maxKey = MAX([RightKey]) FROM [dbo].[text_BookTree] WHERE [BookId] = @bookId

	-- Наименьший левый ключ ВСЕГДА равен 1;
	IF (@minKey <> 1)
	BEGIN
		RAISERROR ('Наименьший левый ключ ВСЕГДА равен 1', 16, 1)
		RETURN 1
	END

	-- Наибольший правый ключ ВСЕГДА равен двойному числу узлов;
	IF (@maxKey <> (@count *2))
	BEGIN
		RAISERROR ('Наибольший правый ключ ВСЕГДА равен двойному числу узлов', 16, 1)
		RETURN 1
	END

	-- Разница между правым и левым ключом ВСЕГДА нечетное число;
	IF EXISTS(SELECT * FROM [dbo].[text_BookTree] WHERE [BookId] = @bookId AND (([RightKey] - [LeftKey]) % 2) = 0)
	BEGIN
		RAISERROR ('Разница между правым и левым ключом ВСЕГДА нечетное число', 16, 1)
		RETURN 1
	END

	-- Если уровень узла нечетное число то тогда левый ключ ВСЕГДА нечетное число, то же самое и для четных чисел;
	IF EXISTS(SELECT * FROM [dbo].[text_BookTree] WHERE [BookId] = @bookId AND (([LeftKey] - [Level] + 2) % 2) = 1)
	BEGIN
		RAISERROR ('Если уровень узла нечетное число то тогда левый ключ ВСЕГДА нечетное число, то же самое и для четных чисел', 16, 1)
		RETURN 1
	END

	-- Ключи ВСЕГДА уникальны, вне зависимости от того правый он или левый;
	/*Выборка по сути осуществляется из одной таблицы, но в разделе FROM эта таблица "виртуально" продублирована 3 раза: из первой мы выбираем все записи по порядку и начинаем сравнивать с записями второй таблицы (раздел WHERE) в результате мы получаем все записи неповторяющихся значений. Для того, что бы определить сколько раз запись не повторялась в таблице, производим группировку (раздел GROUP BY) и получаем число "не повторов" (COUNT(t1.id)). По условию, если все ключи уникальны, то число не повторов будет меньше на одну единицу чем общее количество записей. Для того, чтобы определить количество записей в таблице, берем максимальный правый ключ (MAX(t3.right_key)), так как его значение - двойное число записей, но так как в условии отбора для записи с максимальным правым ключом - максимальный правый ключ будет другим, вводится третья таблица, при этом число "неповторов" увеличивается умножением его на количество записей. SQRT(4*rep +1) - решение уравнения x^2 + x = rep. Если все правильно то результата работы запроса не будет, иначе, получаем список идентификаторов неправильных строк*/
	IF EXISTS(SELECT t1.[BookTreeId]
		FROM [dbo].[text_BookTree] AS t1, [dbo].[text_BookTree] AS t2, [dbo].[text_BookTree] AS t3 
		WHERE t1.[BookId] = @bookId AND t2.[BookId] = @bookId AND t3.[BookId] = @bookId AND t1.[LeftKey] <> t2.[LeftKey] AND t1.[LeftKey] <> t2.[RightKey] AND t1.[RightKey] <> t2.[LeftKey] AND t1.[RightKey] <> t2.[RightKey] 
		GROUP BY t1.[BookTreeId] 
		HAVING MAX(t3.[RightKey]) <> SQRT(4 * COUNT(t1.[BookTreeId]) + 1) + 1)
	BEGIN
		RAISERROR ('Ключи ВСЕГДА уникальны, вне зависимости от того правый он или левый', 16, 1)
		RETURN 1
	END

	RETURN 0
END